package org.study.memcached.cas;

import java.io.IOException;
import java.net.InetSocketAddress;

import net.spy.memcached.CASResponse;
import net.spy.memcached.CASValue;
import net.spy.memcached.MemcachedClient;


public class CASTest {
	
	private static MemcachedClient client = null;
	
	static {
		try {
			client = new MemcachedClient(
                                new InetSocketAddress("10.127.129.152", 11211));
		} catch (IOException o) {
			o.printStackTrace();
		}
	}

	public static void main(String[] args) throws Exception {
		//Firstly, the key should exist.
		//key is "number", value is Integer 1, 7845 is expire time
		client.set("number", 7845, 1);
		
		final CASValue<Object> casValue = client.gets("number");
		System.out.println(casValue.toString());
		
		/**
		 * 测试 进程t1 和 t2同时获得了key “number”对应的cas版本号，但是t1比t2延迟一秒执行
		 * 结果：t2更新成功之后，cas版本号增加，t1再尝试更新旧版本号时提示exists
		 */
		Thread t1 = new Thread() {
			public void run() {
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				CASResponse response = client.cas("number", casValue.getCas(), 3);
				System.out.println("t1:"+response);
			}
		};
		Thread t2 = new Thread() {
			public void run() {
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				CASResponse response = client.cas("number", casValue.getCas(), 2);
				System.out.println("t2:"+response);
			}
		};
		
		t1.start();
		t2.start();
		
//		CASTest testObj = new CASTest();
		//start the multithread environment
//		for (int i = 0; i < 10; i++) {
//			testObj.new ThreadTest("Thread-" + (i + 1)).start();
//		}
	}
	
	/**
	 * Each thread runs many times
	 */
	private class ThreadTest extends Thread {
		
		private  MemcachedClient client = null;
		ThreadTest(String name) throws IOException {
			super(name);
			client = new MemcachedClient(
                                  new InetSocketAddress("10.127.129.152", 11211));
		}
		
		public void run() {
			int i = 0;
			int success = 0;
			while (i < 10) {
				i++;
				CASValue<Object> uniqueValue =client.gets("number");
				CASResponse response = client.cas("number",   
                 uniqueValue.getCas(), (Integer)uniqueValue.getValue() + 1);

				if (response.toString().equals("OK")) {
					success++;
				}
				System.out.println(Thread.currentThread().getName() + " " +  i 
                  + " time " + " update oldValue : " + uniqueValue 
                  +  " , result : " + response);
			}
			
			if (success < 10) {
				System.out.println(Thread.currentThread().getName()
                      + " unsuccessful times : " + (10 - success ));
			}
		}
	}
}